package Domain;

import Persistence.PersistenceController;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author kenneth
 */
public class ClientConnection implements Runnable {
    
    private Socket clientSocket;
    private String email;
    private ObservableManager om;
    
    // Send things to the client
    private ObjectOutputStream objectOutputStream;
    
    // Receive things from the client
    private BufferedReader bufferedReader;
    
    public ClientConnection(Socket clientSocket, ObservableManager om) {
        this.om = om;
        this.clientSocket = clientSocket;
        try {          
            objectOutputStream = new ObjectOutputStream(clientSocket.getOutputStream());
            bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        } catch (IOException ex) {
            Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    @Override
    public void run() {
        boolean authenticated = false;
        do {
            authenticated = authenticateUser();
            try {
                objectOutputStream.writeObject((Object) authenticated);
            } catch (IOException ex) {
                om.updateMessage("Connection with client failed");
                this.closeConnection();
                return;
            }
            if(!authenticated) 
                om.updateMessage("User " + email + " has failed to authenticate");
        }
        while(!authenticated);
        om.updateMessage("User " + email + " has authenticated");
        File dir = new File(email);
        if(!dir.exists()) {
            dir.mkdir();
            om.updateMessage("Client " + email + " has created his rootfolder");
        }
        boolean run = true;
        while(run) {
            String state = null;
            try {
                state = bufferedReader.readLine();
                System.out.println(state);
            } catch (IOException ex) {
                Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
            }
            if(state.equals("login")) {
                run = false;
                this.closeConnection();
            } else if (state.equals("send")) {
                om.updateMessage(email + " is going to send a file");
                this.receiveFile();
            }
        }
        
        
        
    }
    
    private boolean authenticateUser() {
        email = "";
        String password = "";
        try {
            email = bufferedReader.readLine();
            password = bufferedReader.readLine();  
        } catch (IOException ex) {
            om.updateMessage("Connection with client failed");
        }
        return PersistenceController.getController().authenticateUser(email, password);
    }
    
    private void closeConnection() {
        try {
            clientSocket.close();
            om.updateMessage("Closing " + email + "'s connection");
        } catch (IOException ex) {
            Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void receiveFile() {
        try {
            String fileName = email + "\\" + bufferedReader.readLine();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(fileName));
            InputStream inputStream = clientSocket.getInputStream();
            
            byte[] aByte = new byte[1];
            int bytesRead;

            do {
                byteArrayOutputStream.write(aByte);
                bytesRead = inputStream.read(aByte);
            } while (bytesRead != -1);

            bufferedOutputStream.write(byteArrayOutputStream.toByteArray());
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
            this.closeConnection();

            om.updateMessage(email + " uploaded " + fileName);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
    }
   
    public void registrateUser(String email, String paswoord) {
        //TODO
    }
    
}
